#include "usbfunctions.h"
//-----------------------------------------------------------------------------
//  USB MSG
//-----------------------------------------------------------------------------
//this function sends a request through libusb
// and prints the recieved data
int usbMsg(
    usb_dev_handle* handle, char* buffer, size_t buflen,
    int request, int endpoint, int wval)
{
  int cnt = -1;
  short int i;
  if(handle){
    cnt = usb_control_msg(
        handle, USB_TYPE_VENDOR | USB_RECIP_DEVICE | endpoint,
        request, wval, wval, buffer, SAMPLE_COUNT+1, 5000);
    if(cnt < 0){
      fprintf(stderr, "USB error: %s, IGNORING\n", usb_strerror());
    }else if(cnt>0){
      //printf("bytes recieved: %d, buffer length: %d\n",cnt, buflen);
      //for(i=0; i<buflen;i++){
      //  printf("buffer[%d] = %d\n", i, (uint8_t)buffer[i]);
      //}
    }
  }else{
    printf("no valid usb_dev_handle\nTry reconnecting\n");
  }
  return(cnt);
}


//-----------------------------------------------------------------------------
//  CONNECT USB
//-----------------------------------------------------------------------------
usb_dev_handle* connect_device(){
    usb_dev_handle* handle = NULL;
    const unsigned char rawVid[2] =
		{USB_CFG_VENDOR_ID}, rawPid[2] = {USB_CFG_DEVICE_ID};
    char vendor[] = 
		{USB_CFG_VENDOR_NAME, 0}, product[] = {USB_CFG_DEVICE_NAME, 0};
    int cnt, vid, pid;
	usb_init();
    vid = rawVid[1] * 256 + rawVid[0];
    pid = rawPid[1] * 256 + rawPid[0];
    if(usbOpenDevice(&handle, vid, vendor,
		pid, product, NULL, NULL, NULL) != 0)
	{
        fprintf(
            stderr,
            "Could not find USB device \"%s\" with vid=0x%x pid=0x%x\n",
            product, vid, pid);
		exit(1);
    }
	return(handle);
}


//-----------------------------------------------------------------------------
//  NSLEEP
//-----------------------------------------------------------------------------
// sleep for a few nanoseconds
void nsleep(long nanoseconds){
	#ifndef __WINDOWS_FFS__
		struct timespec sleepy;
		sleepy.tv_sec = 0;
		sleepy.tv_nsec = nanoseconds;
		nanosleep(&sleepy, NULL);
	#else
		Sleep(nanoseconds/1000000);
	#endif
	
}

//-----------------------------------------------------------------------------
//  WRITE BUFFER
//-----------------------------------------------------------------------------
void writeBuffer(char* buffer, int buflen, FILE* f){
	char s[20];
	int s_length, i;
	for(i=0;i<buflen;i++){
		s_length = sprintf(s, "%d,", (uint8_t)buffer[i]);
		fwrite(s, s_length, 1, f);
	}
	//next line at the end
	s_length = sprintf(s, "\r\n");
	fwrite(s, s_length, 1, f);
}

//-----------------------------------------------------------------------------
//  NEW DATAFILE
//-----------------------------------------------------------------------------
//clears and opens data.csv for appending
FILE* newDatafile(){
	FILE* data_file = fopen("data.csv", "w"); //clear file
	fclose(data_file);
	data_file = fopen("data.csv", "a");
	return(data_file);
}


//-----------------------------------------------------------------------------
//  GRAB DATA
//-----------------------------------------------------------------------------
int grabData(usb_dev_handle* handle, char* buffer){
	int recv = usbMsg(
		handle, buffer, SAMPLE_COUNT,
		CUSTOM_RQ_NEXT_PULSE, USB_ENDPOINT_OUT, DEFAULT_PRESCALE);
	printf("next pulse returned: %d bytes\n", recv);
	//sleep for 6 ms, then ask for data (also prints received data)
	nsleep(6000000);
	recv = usbMsg(
		handle, buffer, SAMPLE_COUNT,
		CUSTOM_RQ_GET_DATA, USB_ENDPOINT_IN,0);
	return(recv);
}
